package cn.stylefeng.guns.modular.vote.service.impl;

import cn.hutool.core.bean.BeanUtil;
import cn.hutool.core.util.ObjectUtil;
import cn.stylefeng.roses.kernel.rule.exception.base.ServiceException;
import cn.stylefeng.guns.modular.vote.entity.Works;
import cn.stylefeng.guns.modular.vote.enums.WorksExceptionEnum;
import cn.stylefeng.guns.modular.vote.mapper.WorksMapper;
import cn.stylefeng.guns.modular.vote.pojo.request.WorksRequest;
import cn.stylefeng.guns.modular.vote.service.WorksService;
import cn.stylefeng.roses.kernel.auth.api.context.LoginContext;
import cn.stylefeng.roses.kernel.db.api.factory.PageFactory;
import cn.stylefeng.roses.kernel.db.api.factory.PageResultFactory;
import cn.stylefeng.roses.kernel.db.api.pojo.page.PageResult;
import cn.stylefeng.roses.kernel.system.modular.organization.entity.HrOrganization;
import cn.stylefeng.roses.kernel.system.modular.organization.service.HrOrganizationService;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.github.yulichang.base.MPJBaseServiceImpl;
import com.github.yulichang.query.MPJLambdaQueryWrapper;
import com.github.yulichang.wrapper.MPJLambdaWrapper;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import java.util.List;
import java.util.Date;

/**
 * 作品表;业务实现层
 *
 * @author songq
 * @date 2025/04/22 14:49
 */
@Service
public class WorksServiceImpl extends MPJBaseServiceImpl<WorksMapper, Works> implements WorksService {

	@Override
    public void add(WorksRequest worksRequest) {
        Works works = new Works();
        BeanUtil.copyProperties(worksRequest, works);
        works.setCreatedBy(LoginContext.me().getLoginUser().getAccount());
        works.setCreatedTime(new Date());
        this.save(works);
    }

    @Override
    public void del(WorksRequest worksRequest) {
        Works works = this.queryWorks(worksRequest);
        this.removeById(works.getWorkId());
    }

    @Override
    public void edit(WorksRequest worksRequest) {
        Works works = this.queryWorks(worksRequest);
        BeanUtil.copyProperties(worksRequest, works);
        works.setUpdatedBy(LoginContext.me().getLoginUser().getAccount());
        works.setUpdatedTime(new Date());
        this.updateById(works);
    }

    @Override
    public Works detail(WorksRequest worksRequest) {
        return this.queryWorks(worksRequest);
    }

    @Override
    public PageResult<Works> findPage(WorksRequest worksRequest) {
        MPJLambdaWrapper<Works> mpjWrapper = this.createMPJWrapper(worksRequest);
        mpjWrapper.selectAll(Works.class)
                .leftJoin(HrOrganization.class,HrOrganization::getOrgId,Works::getWorkDept)
                .orderByAsc(HrOrganization::getOrgSort)
                .orderByAsc(Works::getWorkSort);
        Page<Works> works = this.selectJoinListPage(PageFactory.defaultPage(),Works.class, mpjWrapper);
        return PageResultFactory.createPageResult(works);
    }

    @Override
    public List<Works> findList(WorksRequest worksRequest) {
        MPJLambdaWrapper<Works> mpjWrapper = this.createMPJWrapper(worksRequest);
        mpjWrapper.selectAll(Works.class)
                .leftJoin(HrOrganization.class,HrOrganization::getOrgId,Works::getWorkDept)
                .orderByAsc(HrOrganization::getOrgSort)
                .orderByAsc(Works::getWorkSort);
        return this.selectJoinList(Works.class, mpjWrapper);
    }

    /**
     * 获取信息
     *
     * @author songq
     * @date 2025/04/22 14:49
     */
    private Works queryWorks(WorksRequest worksRequest) {
        Works works = this.getById(worksRequest.getWorkId());
        if (ObjectUtil.isEmpty(works)) {
            throw new ServiceException(WorksExceptionEnum.WORKS_NOT_EXISTED);
        }
        return works;
    }

    /**
     * 创建查询wrapper
     *
     * @author songq
     * @date 2025/04/22 14:49
     */
    private LambdaQueryWrapper<Works> createWrapper(WorksRequest worksRequest) {
        LambdaQueryWrapper<Works> queryWrapper = new LambdaQueryWrapper<>();

        Long workId = worksRequest.getWorkId();
        Long workDept = worksRequest.getWorkDept();
        String workTitle = worksRequest.getWorkTitle();
        String workDesc = worksRequest.getWorkDesc();
        String workImg = worksRequest.getWorkImg();
        String workUrl = worksRequest.getWorkUrl();
        String workAuthor = worksRequest.getWorkAuthor();
        Integer workSort = worksRequest.getWorkSort();
        Integer voteNum = worksRequest.getVoteNum();
        String createdBy = worksRequest.getCreatedBy();
        String createdTime = worksRequest.getCreatedTime();
        String updatedBy = worksRequest.getUpdatedBy();
        String updatedTime = worksRequest.getUpdatedTime();

        queryWrapper.eq(ObjectUtil.isNotNull(workId), Works::getWorkId, workId);
        queryWrapper.eq(ObjectUtil.isNotNull(workDept), Works::getWorkDept, workDept);
        queryWrapper.like(ObjectUtil.isNotEmpty(workTitle), Works::getWorkTitle, workTitle);
        queryWrapper.like(ObjectUtil.isNotEmpty(workDesc), Works::getWorkDesc, workDesc);
        queryWrapper.like(ObjectUtil.isNotEmpty(workImg), Works::getWorkImg, workImg);
        queryWrapper.like(ObjectUtil.isNotEmpty(workUrl), Works::getWorkUrl, workUrl);
        queryWrapper.like(ObjectUtil.isNotEmpty(workAuthor), Works::getWorkAuthor, workAuthor);
        queryWrapper.eq(ObjectUtil.isNotNull(workSort), Works::getWorkSort, workSort);
        queryWrapper.eq(ObjectUtil.isNotNull(voteNum), Works::getVoteNum, voteNum);
        queryWrapper.like(ObjectUtil.isNotEmpty(createdBy), Works::getCreatedBy, createdBy);
        queryWrapper.eq(ObjectUtil.isNotNull(createdTime), Works::getCreatedTime, createdTime);
        queryWrapper.like(ObjectUtil.isNotEmpty(updatedBy), Works::getUpdatedBy, updatedBy);
        queryWrapper.eq(ObjectUtil.isNotNull(updatedTime), Works::getUpdatedTime, updatedTime);

        return queryWrapper;
    }

    private MPJLambdaWrapper<Works> createMPJWrapper(WorksRequest worksRequest) {
        MPJLambdaWrapper<Works> queryWrapper = new MPJLambdaWrapper<>();

        Long workId = worksRequest.getWorkId();
        Long workDept = worksRequest.getWorkDept();
        String workTitle = worksRequest.getWorkTitle();
        String workDesc = worksRequest.getWorkDesc();
        String workImg = worksRequest.getWorkImg();
        String workUrl = worksRequest.getWorkUrl();
        String workAuthor = worksRequest.getWorkAuthor();
        Integer workSort = worksRequest.getWorkSort();
        Integer voteNum = worksRequest.getVoteNum();
        String createdBy = worksRequest.getCreatedBy();
        String createdTime = worksRequest.getCreatedTime();
        String updatedBy = worksRequest.getUpdatedBy();
        String updatedTime = worksRequest.getUpdatedTime();

        queryWrapper.eq(ObjectUtil.isNotNull(workId), Works::getWorkId, workId);
        queryWrapper.eq(ObjectUtil.isNotNull(workDept), Works::getWorkDept, workDept);
        queryWrapper.like(ObjectUtil.isNotEmpty(workTitle), Works::getWorkTitle, workTitle);
        queryWrapper.like(ObjectUtil.isNotEmpty(workDesc), Works::getWorkDesc, workDesc);
        queryWrapper.like(ObjectUtil.isNotEmpty(workImg), Works::getWorkImg, workImg);
        queryWrapper.like(ObjectUtil.isNotEmpty(workUrl), Works::getWorkUrl, workUrl);
        queryWrapper.like(ObjectUtil.isNotEmpty(workAuthor), Works::getWorkAuthor, workAuthor);
        queryWrapper.eq(ObjectUtil.isNotNull(workSort), Works::getWorkSort, workSort);
        queryWrapper.eq(ObjectUtil.isNotNull(voteNum), Works::getVoteNum, voteNum);
        queryWrapper.like(ObjectUtil.isNotEmpty(createdBy), Works::getCreatedBy, createdBy);
        queryWrapper.eq(ObjectUtil.isNotNull(createdTime), Works::getCreatedTime, createdTime);
        queryWrapper.like(ObjectUtil.isNotEmpty(updatedBy), Works::getUpdatedBy, updatedBy);
        queryWrapper.eq(ObjectUtil.isNotNull(updatedTime), Works::getUpdatedTime, updatedTime);

        return queryWrapper;
    }

}